home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / Xsun / RCS / sunMouse.c,v < prev    next >
Encoding:
Text File  |  1990-04-23  |  18.7 KB  |  737 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     90.04.22.23.36.00;  author tve;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     90.02.16.17.40.20;  author tve;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @Original X11R4 distribution
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @
  28. @
  29. text
  30. @/*-
  31.  * sunMouse.c --
  32.  *    Functions for playing cat and mouse... sorry.
  33.  *
  34.  * Copyright (c) 1987 by the Regents of the University of California
  35.  *
  36.  * Permission to use, copy, modify, and distribute this
  37.  * software and its documentation for any purpose and without
  38.  * fee is hereby granted, provided that the above copyright
  39.  * notice appear in all copies.  The University of California
  40.  * makes no representations about the suitability of this
  41.  * software for any purpose.  It is provided "as is" without
  42.  * express or implied warranty.
  43.  *
  44.  *
  45.  */
  46.  
  47. /************************************************************
  48. Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
  49.  
  50.                     All Rights Reserved
  51.  
  52. Permission  to  use,  copy,  modify,  and  distribute   this
  53. software  and  its documentation for any purpose and without
  54. fee is hereby granted, provided that the above copyright no-
  55. tice  appear  in all copies and that both that copyright no-
  56. tice and this permission notice appear in  supporting  docu-
  57. mentation,  and  that the names of Sun or MIT not be used in
  58. advertising or publicity pertaining to distribution  of  the
  59. software  without specific prior written permission. Sun and
  60. M.I.T. make no representations about the suitability of this
  61. software for any purpose. It is provided "as is" without any
  62. express or implied warranty.
  63.  
  64. SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
  65. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
  66. NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
  67. ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  68. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
  69. PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
  70. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
  71. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  72.  
  73. ********************************************************/
  74.  
  75. #ifndef    lint
  76. static char sccsid[] = "%W %G Copyright 1987 Sun Micro";
  77. #endif
  78.  
  79. #define NEED_EVENTS
  80. #include    "sun.h"
  81. #include    "mipointer.h"
  82. #include    "misprite.h"
  83.  
  84. Bool ActiveZaphod = TRUE;
  85.  
  86. static long sunEventTime();
  87. static Bool sunCursorOffScreen();
  88. static void sunCrossScreen();
  89. extern void miPointerQueueEvent();
  90.  
  91. miPointerCursorFuncRec sunPointerCursorFuncs = {
  92.     sunEventTime,
  93.     sunCursorOffScreen,
  94.     sunCrossScreen,
  95.     miPointerQueueEvent,
  96. };
  97.  
  98. typedef struct {
  99.     int        bmask;        /* Current button state */
  100.     Bool    mouseMoved;        /* Mouse has moved */
  101. } SunMsPrivRec, *SunMsPrivPtr;
  102.  
  103. static void           sunMouseCtrl();
  104. static int           sunMouseGetMotionEvents();
  105. static Mouse_Event     *sunMouseGetEvents();
  106. static void           sunMouseProcessEvent();
  107. static void           sunMouseDoneEvents();
  108.  
  109. static SunMsPrivRec    sunMousePriv;
  110.  
  111. static PtrPrivRec     sysMousePriv = {
  112.     -1,                /* Descriptor to device */
  113.     sunMouseGetEvents,        /* Function to read events */
  114.     sunMouseProcessEvent,    /* Function to process an event */
  115.     sunMouseDoneEvents,        /* When all the events have been */
  116.                 /* handled, this function will be */
  117.                 /* called. */
  118.     0,                /* Current x movement of pointer */
  119.     0,                /* Current y movement */
  120.     (pointer)&sunMousePriv,    /* Field private to device */
  121. };
  122.  
  123. /*-
  124.  *-----------------------------------------------------------------------
  125.  * sunMouseProc --
  126.  *    Handle the initialization, etc. of a mouse
  127.  *
  128.  * Results:
  129.  *    none.
  130.  *
  131.  * Side Effects:
  132.  *
  133.  * Note:
  134.  *    When using sunwindows, all input comes off a single fd, stored in the
  135.  *    global windowFd.  Therefore, only one device should be enabled and
  136.  *    disabled, even though the application still sees both mouse and
  137.  *    keyboard.  We have arbitrarily chosen to enable and disable windowFd
  138.  *    in the keyboard routine sunKbdProc rather than in sunMouseProc.
  139.  *
  140.  *    In Sprite, things work like under suntools, in that /dev/mouse
  141.  *    handles both mouse and keyboard.
  142.  *
  143.  *-----------------------------------------------------------------------
  144.  */
  145. int
  146. sunMouseProc (pMouse, what)
  147.     DevicePtr      pMouse;       /* Mouse to play with */
  148.     int              what;            /* What to do with it */
  149. {
  150.     register int  fd;
  151.     int              format;
  152.     static int      oformat;
  153.     BYTE          map[4];
  154.  
  155.     switch (what) {
  156.     case DEVICE_INIT:
  157.         if (pMouse != LookupPointerDevice()) {
  158.         ErrorF ("Cannot open non-system mouse");    
  159.         return (!Success);
  160.         }
  161.  
  162.         sunMousePriv.bmask = 0;
  163.         sunMousePriv.mouseMoved = FALSE;
  164.         sysMousePriv.dx = 0;
  165.         sysMousePriv.dy = 0;
  166.  
  167.         pMouse->devicePrivate = (pointer) &sysMousePriv;
  168.         pMouse->on = FALSE;
  169.         map[1] = 1;
  170.         map[2] = 2;
  171.         map[3] = 3;
  172.         InitPointerDeviceStruct(
  173.         pMouse, map, 3, sunMouseGetMotionEvents, sunMouseCtrl, 0);
  174.         break;
  175.  
  176.     case DEVICE_ON:
  177.         pMouse->on = TRUE;
  178.         break;
  179.  
  180.     case DEVICE_CLOSE:
  181.         break;
  182.  
  183.     case DEVICE_OFF:
  184.         pMouse->on = FALSE;
  185.         break;
  186.     }
  187.     return (Success);
  188. }
  189.         
  190. /*-
  191.  *-----------------------------------------------------------------------
  192.  * sunMouseCtrl --
  193.  *    Alter the control parameters for the mouse. Since acceleration
  194.  *    etc. is done from the PtrCtrl record in the mouse's device record,
  195.  *    there's nothing to do here.
  196.  *
  197.  * Results:
  198.  *    None.
  199.  *
  200.  * Side Effects:
  201.  *    None.
  202.  *
  203.  *-----------------------------------------------------------------------
  204.  */
  205. /*ARGSUSED*/
  206. static void
  207. sunMouseCtrl (pMouse)
  208.     DevicePtr      pMouse;
  209. {
  210. }
  211.  
  212. /*-
  213.  *-----------------------------------------------------------------------
  214.  * sunMouseGetMotionEvents --
  215.  *    Return the (number of) motion events in the "motion history
  216.  *    buffer" (snicker) between the given times.
  217.  *
  218.  * Results:
  219.  *    The number of events stuffed.
  220.  *
  221.  * Side Effects:
  222.  *    The relevant xTimecoord's are stuffed in the passed memory.
  223.  *
  224.  *-----------------------------------------------------------------------
  225.  */
  226. /*ARGSUSED*/
  227. static int
  228. sunMouseGetMotionEvents (buff, start, stop, pScreen)
  229.     CARD32 start, stop;
  230.     xTimecoord *buff;
  231.     ScreenPtr pScreen;
  232. {
  233.     return 0;
  234. }
  235.  
  236. /*-
  237.  *-----------------------------------------------------------------------
  238.  * sunMouseGetEvents --
  239.  *    Return the events waiting in the wings for the given mouse.
  240.  *
  241.  * Results:
  242.  *    A pointer to an array of Mouse_Events or (Mouse_Event *)0 if no events
  243.  *    The number of events contained in the array.
  244.  *    A boolean as to whether more events might be available.
  245.  *
  246.  * Side Effects:
  247.  *    None.
  248.  *-----------------------------------------------------------------------
  249.  */
  250. static Mouse_Event *
  251. sunMouseGetEvents (pMouse, pNumEvents)
  252.     DevicePtr      pMouse;        /* Mouse to read */
  253.     int              *pNumEvents;        /* Place to return number of events */
  254. {
  255.     return (Mouse_Event *)0;
  256. }
  257.  
  258.  
  259. /*-
  260.  *-----------------------------------------------------------------------
  261.  * MouseAccelerate --
  262.  *    Given a delta and a mouse, return the acceleration of the delta.
  263.  *
  264.  * Results:
  265.  *    The corrected delta
  266.  *
  267.  * Side Effects:
  268.  *    None.
  269.  *
  270.  *-----------------------------------------------------------------------
  271.  */
  272. static short
  273. MouseAccelerate (pMouse, delta)
  274.     DevicePtr      pMouse;
  275.     int              delta;
  276. {
  277.     register int  sgn = sign(delta);
  278.     register PtrCtrl *pCtrl;
  279.  
  280.     delta = abs(delta);
  281.     pCtrl = &((DeviceIntPtr) pMouse)->ptrfeed->ctrl;
  282.  
  283.     if (delta > pCtrl->threshold) {
  284.     return ((short) (sgn * (pCtrl->threshold +
  285.                 ((delta - pCtrl->threshold) * pCtrl->num) /
  286.                 pCtrl->den)));
  287.     } else {
  288.     return ((short) (sgn * delta));
  289.     }
  290. }
  291.  
  292. /*-
  293.  *-----------------------------------------------------------------------
  294.  * sunMouseProcessEvent --
  295.  *    Given a Firm_event for a mouse, pass it off the the dix layer
  296.  *    properly converted...
  297.  *
  298.  * Results:
  299.  *    None.
  300.  *
  301.  * Side Effects:
  302.  *    The cursor may be redrawn...? devPrivate/x/y will be altered.
  303.  *
  304.  *-----------------------------------------------------------------------
  305.  */
  306. static void
  307. sunMouseProcessEvent (pMouse, ev)
  308.     DevicePtr      pMouse;       /* Mouse from which the event came */
  309.     Mouse_Event      *ev;            /* Event to process */
  310. {
  311.     xEvent        xE;
  312.     register PtrPrivPtr    pPriv;    /* Private data for pointer */
  313.     register SunMsPrivPtr pSunPriv; /* Private data for mouse */
  314.     register int      bmask;    /* Temporary button mask */
  315.     register int      button;
  316.  
  317.     pPriv = (PtrPrivPtr)pMouse->devicePrivate;
  318.     pSunPriv = (SunMsPrivPtr) pPriv->devPrivate;
  319.  
  320.     xE.u.keyButtonPointer.time = ev->time;
  321.     bmask = ev->key ^ pSunPriv->bmask;
  322.  
  323.     /*
  324.      * When we detect a change in the mouse coordinates, we call
  325.      * the cursor module to move the cursor. It has the option of
  326.      * simply removing the cursor or just shifting it a bit.
  327.      * If it is removed, DIX will restore it before we goes to sleep...
  328.      *
  329.      * What should be done if it goes off the screen? Move to another
  330.      * screen? For now, we just force the pointer to stay on the
  331.      * screen...
  332.      *
  333.      * For some reason, motion up generates a positive y delta
  334.      * and motion down a negative delta, so we must subtract
  335.      * here instead of add...
  336.      */
  337.     if (ev->deltaX) {
  338.         pPriv->dx += MouseAccelerate (pMouse, ev->deltaX);
  339.         ((SunMsPrivPtr)pPriv->devPrivate)->mouseMoved = TRUE;
  340.     }
  341.  
  342.     if (ev->deltaY) {
  343.         pPriv->dy -= MouseAccelerate (pMouse, ev->deltaY);
  344.         ((SunMsPrivPtr)pPriv->devPrivate)->mouseMoved = TRUE;
  345.     }
  346.  
  347.     if (ev->key ^ pSunPriv->bmask) {
  348.     sunMouseDoneEvents (pMouse, FALSE);
  349.     }
  350.  
  351.     xE.u.keyButtonPointer.time = ev->time;
  352.     for (bmask = 4, button = 1; bmask != 0; bmask >>= 1, button++) {
  353.     if ((ev->key & bmask) != (pSunPriv->bmask & bmask)) {
  354.         xE.u.u.type = (ev->key & bmask) ? ButtonRelease : ButtonPress;
  355.         xE.u.u.detail = button;
  356.  
  357.         miPointerPosition (screenInfo.screens[0],
  358.         &xE.u.keyButtonPointer.rootX,
  359.         &xE.u.keyButtonPointer.rootY);
  360.  
  361.         (* pMouse->processInputProc) (&xE, pMouse, 1);
  362.     }
  363.     }
  364.     pSunPriv->bmask = ev->key;
  365.     lastEventTime = ev->time;
  366. }
  367.  
  368. /*ARGSUSED*/
  369. static Bool
  370. sunCursorOffScreen (pScreen, x, y)
  371.     ScreenPtr    *pScreen;
  372.     int        *x, *y;
  373. {
  374.     int        index;
  375.  
  376.     /*
  377.      * Active Zaphod implementation:
  378.      *    increment or decrement the current screen
  379.      *    if the x is to the right or the left of
  380.      *    the current screen.
  381.      */
  382.     if (ActiveZaphod &&
  383.     screenInfo.numScreens > 1 && (*x >= (*pScreen)->width || *x < 0))
  384.     {
  385.     index = (*pScreen)->myNum;
  386.     if (*x < 0)
  387.     {
  388.         index = (index ? index : screenInfo.numScreens) - 1;
  389.         *pScreen = screenInfo.screens[index];
  390.         *x += (*pScreen)->width;
  391.     }
  392.     else
  393.     {
  394.         *x -= (*pScreen)->width;
  395.         index = (index + 1) % screenInfo.numScreens;
  396.         *pScreen = screenInfo.screens[index];
  397.     }
  398.     return TRUE;
  399.     }
  400.     return FALSE;
  401. }
  402.  
  403. /*ARGSUSED*/
  404. static long
  405. sunEventTime (pScreen)
  406.     ScreenPtr    pScreen;
  407. {
  408.     return lastEventTime;
  409. }
  410.  
  411. static void
  412. sunCrossScreen (pScreen, entering)
  413.     ScreenPtr    pScreen;
  414.     Bool    entering;
  415. {
  416.     unsigned char  select;
  417.  
  418.     select = 1;
  419.     if (entering)
  420.     select = 0;
  421.     if (sunFbs[pScreen->myNum].EnterLeave)
  422.     (*sunFbs[pScreen->myNum].EnterLeave) (pScreen, select);
  423. }
  424.  
  425. /*-
  426.  *-----------------------------------------------------------------------
  427.  * sunMouseDoneEvents --
  428.  *    Finish off any mouse motions we haven't done yet. (At the moment
  429.  *    this code is unused since we never save mouse motions as I'm
  430.  *    unsure of the effect of getting a keystroke at a given [x,y] w/o
  431.  *    having gotten a motion event to that [x,y])
  432.  *
  433.  * Results:
  434.  *    None.
  435.  *
  436.  * Side Effects:
  437.  *    A MotionNotify event may be generated.
  438.  *
  439.  *-----------------------------------------------------------------------
  440.  */
  441. /*ARGSUSED*/
  442. static void
  443. sunMouseDoneEvents (pMouse,final)
  444.     DevicePtr      pMouse;
  445.     Bool      final;
  446. {
  447.     PtrPrivPtr      pPriv;
  448.     SunMsPrivPtr  pSunPriv;
  449.     int          dx, dy;
  450.  
  451.     pPriv = (PtrPrivPtr) pMouse->devicePrivate;
  452.     pSunPriv = (SunMsPrivPtr) pPriv->devPrivate;
  453.  
  454.     if (pSunPriv->mouseMoved) {
  455.     dx = pPriv->dx;
  456.     dy = pPriv->dy;
  457.     pPriv->dx = 0;
  458.     pPriv->dy = 0;
  459.     pSunPriv->mouseMoved = FALSE;
  460.     miPointerDeltaCursor (screenInfo.screens[0], dx, dy, TRUE);
  461.     }
  462. }
  463. @
  464.  
  465.  
  466. 1.1
  467. log
  468. @Initial revision
  469. @
  470. text
  471. @d76 1
  472. a76 1
  473. static Firm_event     *sunMouseGetEvents();
  474. d111 3
  475. a132 19
  476.         if (! sunUseSunWindows()) {
  477.         if (sysMousePriv.fd >= 0) {
  478.             fd = sysMousePriv.fd;
  479.         } else {
  480.             fd = open ("/dev/mouse", O_RDWR, 0);
  481.             if (fd < 0) {
  482.             Error ("Opening /dev/mouse");
  483.             return (!Success);
  484.             }
  485.             if (fcntl (fd, F_SETFL, (FNDELAY|FASYNC)) < 0
  486.             || fcntl(fd, F_SETOWN, getpid()) < 0) {
  487.                 perror("sunMouseProc");
  488.                 ErrorF("Can't set up mouse on fd %d\n", fd);
  489.             }
  490.             
  491.             sysMousePriv.fd = fd;
  492.         }
  493.         }
  494.  
  495. a147 15
  496.         if (! sunUseSunWindows()) {
  497.         if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd,
  498.             VUIDGFORMAT, &oformat) < 0) {
  499.             Error ("VUIDGFORMAT");
  500.             return(!Success);
  501.         }
  502.         format = VUID_FIRM_EVENT;
  503.         if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd,
  504.             VUIDSFORMAT, &format) < 0) {
  505.             Error ("VUIDSFORMAT");
  506.             return(!Success);
  507.         }
  508.         AddEnabledDevice (((PtrPrivPtr)pMouse->devicePrivate)->fd);
  509.         }
  510.  
  511. a151 6
  512.         if (! sunUseSunWindows()) {
  513.         if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd,
  514.             VUIDSFORMAT, &oformat) < 0) {
  515.             Error ("VUIDSFORMAT");
  516.         }
  517.         }
  518. a155 3
  519.         if (! sunUseSunWindows()) {
  520.         RemoveEnabledDevice (((PtrPrivPtr)pMouse->devicePrivate)->fd);
  521.         }
  522. d213 1
  523. a213 1
  524.  *    A pointer to an array of Firm_events or (Firm_event *)0 if no events
  525. d221 2
  526. a222 2
  527. static Firm_event *
  528. sunMouseGetEvents (pMouse, pNumEvents, pAgain)
  529. a224 1
  530.     Bool      *pAgain;        /* whether more might be available */
  531. d226 1
  532. a226 21
  533.     int              nBytes;        /* number of bytes of events available. */
  534.     register PtrPrivPtr      pPriv;
  535.     static Firm_event    evBuf[MAXEVENTS];   /* Buffer for Firm_events */
  536.  
  537.     pPriv = (PtrPrivPtr) pMouse->devicePrivate;
  538.  
  539.     nBytes = read (pPriv->fd, evBuf, sizeof(evBuf));
  540.  
  541.     if (nBytes < 0) {
  542.     if (errno == EWOULDBLOCK) {
  543.         *pNumEvents = 0;
  544.         *pAgain = FALSE;
  545.     } else {
  546.         Error ("Reading mouse");
  547.         FatalError ("Could not read from mouse");
  548.     }
  549.     } else {
  550.     *pNumEvents = nBytes / sizeof (Firm_event);
  551.     *pAgain = (nBytes == sizeof (evBuf));
  552.     }
  553.     return (evBuf);
  554. d278 1
  555. a278 1
  556. sunMouseProcessEvent (pMouse, fe)
  557. d280 1
  558. a280 1
  559.     Firm_event      *fe;            /* Event to process */
  560. d286 1
  561. d291 40
  562. a330 1
  563.     xE.u.keyButtonPointer.time = TVTOMILLI(fe->time);
  564. d332 1
  565. a332 35
  566.     switch (fe->id)
  567.     {
  568.     case MS_LEFT:
  569.     case MS_MIDDLE:
  570.     case MS_RIGHT:
  571.     /*
  572.      * A button changed state. Sometimes we will get two events
  573.      * for a single state change. Should we get a button event which
  574.      * reflects the current state of affairs, that event is discarded.
  575.      *
  576.      * Mouse buttons start at 1.
  577.      */
  578.     xE.u.u.detail = (fe->id - MS_LEFT) + 1;
  579.     bmask = 1 << xE.u.u.detail;
  580.     if (fe->value == VKEY_UP) {
  581.         if (pSunPriv->bmask & bmask) {
  582.         xE.u.u.type = ButtonRelease;
  583.         pSunPriv->bmask &= ~bmask;
  584.         } else {
  585.         return;
  586.         }
  587.     } else {
  588.         if ((pSunPriv->bmask & bmask) == 0) {
  589.         xE.u.u.type = ButtonPress;
  590.         pSunPriv->bmask |= bmask;
  591.         } else {
  592.         return;
  593.         }
  594.     }
  595.     /*
  596.      * If the mouse has moved, we must update any interested client
  597.      * as well as DIX before sending a button event along.
  598.      */
  599.     if (pSunPriv->mouseMoved) {
  600.         sunMouseDoneEvents (pMouse, FALSE);
  601. a333 46
  602.     
  603.     miPointerPosition (screenInfo.screens[0],
  604.                &xE.u.keyButtonPointer.rootX,
  605.                &xE.u.keyButtonPointer.rootY);
  606.     
  607.     (* pMouse->processInputProc) (&xE, pMouse, 1);
  608.     break;
  609.     case LOC_X_DELTA:
  610.     /*
  611.      * When we detect a change in the mouse coordinates, we call
  612.      * the cursor module to move the cursor. It has the option of
  613.      * simply removing the cursor or just shifting it a bit.
  614.      * If it is removed, DIX will restore it before we goes to sleep...
  615.      *
  616.      * What should be done if it goes off the screen? Move to another
  617.      * screen? For now, we just force the pointer to stay on the
  618.      * screen...
  619.      */
  620.     pPriv->dx += MouseAccelerate (pMouse, fe->value);
  621.  
  622. #ifdef    SUN_ALL_MOTION
  623.     miPointerDeltaCursor (screenInfo.screens[0], pPriv->dx, pPriv->dy, TRUE);
  624.     pPriv->dx = 0;
  625.     pPriv->dy = 0;
  626. #else
  627.     ((SunMsPrivPtr)pPriv->devPrivate)->mouseMoved = TRUE;
  628. #endif
  629.     break;
  630.     case LOC_Y_DELTA:
  631.     /*
  632.      * For some reason, motion up generates a positive y delta
  633.      * and motion down a negative delta, so we must subtract
  634.      * here instead of add...
  635.      */
  636.     pPriv->dy -= MouseAccelerate (pMouse, fe->value);
  637. #ifdef SUN_ALL_MOTION
  638.     miPointerDeltaCursor (screenInfo.screens[0], pPriv->dx, pPriv->dy, TRUE);
  639.     pPriv->dx = 0;
  640.     pPriv->dy = 0;
  641. #else
  642.     ((SunMsPrivPtr)pPriv->devPrivate)->mouseMoved = TRUE;
  643. #endif SUN_ALL_MOTION
  644.     break;
  645.     default:
  646.     FatalError ("sunMouseProcessEvent: unrecognized id\n");
  647.     break;
  648. d335 2
  649. d387 1
  650. a387 1
  651.     u_char  select;
  652. a433 83
  653.  
  654. #ifdef SUN_WINDOWS
  655.  
  656. /*
  657.  * Process a sunwindows mouse event.  The possible events are
  658.  *   LOC_MOVE
  659.  *   MS_LEFT
  660.  *   MS_MIDDLE
  661.  *   MS_RIGHT
  662.  */
  663.  
  664. void
  665. sunMouseProcessEventSunWin(pMouse,se)
  666.     DeviceRec *pMouse;
  667.     register struct inputevent *se;
  668. {   
  669.     xEvent            xE;
  670.     register int          bmask;    /* Temporary button mask */
  671.     register PtrPrivPtr        pPriv;    /* Private data for pointer */
  672.     register SunMsPrivPtr    pSunPriv; /* Private data for mouse */
  673.     short            x, y;
  674.  
  675.     pPriv = (PtrPrivPtr)pMouse->devicePrivate;
  676.  
  677.     switch (event_id(se)) {
  678.         case MS_LEFT:
  679.         case MS_MIDDLE:
  680.         case MS_RIGHT:
  681.         /*
  682.          * A button changed state. Sometimes we will get two events
  683.          * for a single state change. Should we get a button event which
  684.          * reflects the current state of affairs, that event is discarded.
  685.          *
  686.          * Mouse buttons start at 1.
  687.          */
  688.         pSunPriv = (SunMsPrivPtr) pPriv->devPrivate;
  689.         xE.u.keyButtonPointer.time = TVTOMILLI(event_time(se));
  690.         xE.u.u.detail = (event_id(se) - MS_LEFT) + 1;
  691.         bmask = 1 << xE.u.u.detail;
  692.         if (win_inputnegevent(se)) {
  693.         if (pSunPriv->bmask & bmask) {
  694.             xE.u.u.type = ButtonRelease;
  695.             pSunPriv->bmask &= ~bmask;
  696.         } else {
  697.             return;
  698.         }
  699.         } else {
  700.         if ((pSunPriv->bmask & bmask) == 0) {
  701.             xE.u.u.type = ButtonPress;
  702.             pSunPriv->bmask |= bmask;
  703.         } else {
  704.             return;
  705.         }
  706.         }
  707.         miPointerPosition (screenInfo.screens[0],
  708.             &xE.u.keyButtonPointer.rootX, &xE.u.keyButtonPointer.rootY);
  709.             (* pMouse->processInputProc) (&xE, pMouse, 1);
  710.             break;
  711.         case LOC_MOVE:
  712.         /*
  713.          * Tell mi to go ahead and generate the event.
  714.          */
  715.         miPointerMoveCursor(screenInfo.screens[0], event_x(se),
  716.         event_y(se), TRUE);
  717.  
  718.         /*
  719.          * Find out if the mouse got constrained. If it did
  720.          * then we have to tell SunWindows about it.
  721.          */
  722.         miPointerPosition (screenInfo.screens[0], &x, &y);
  723.         if (x != event_x(se) || y != event_y(se))
  724.             /*
  725.                  * Tell SunWindows that X is constraining the mouse
  726.                  * cursor so that the server and SunWindows stay in sync.
  727.              */
  728.             win_setmouseposition(windowFd, x, y);
  729.         break;
  730.     default:
  731.         FatalError ("sunMouseProcessEventSunWin: unrecognized id\n");
  732.         break;
  733.     }
  734. }
  735. #endif SUN_WINDOWS
  736. @
  737.